# -*- coding: utf-8 -*-
# @Time    : 2016/9/22
import re
from sympy import sympify
from mathsolver.functions.base import BaseFunction, BasePoly, new_latex


class DingYiShiBianHuanJiSuan(BaseFunction):
    """导数的定义式变换计算"""

    @staticmethod
    def delta_process(new_latex_expression):
        p = re.compile(r"\\Delta\{\\left \((.*?) \\right \)\}")
        return p.sub(r"\Delta \1", new_latex_expression)

    def solver(self, *args):
        limit_obj = args[0]
        exp, variable, const, direction = limit_obj.expression, limit_obj.var, limit_obj.value, limit_obj.dir

        # 从方程中抽取出分子分母，方程形式为：
        #   (f(inner_num1) - f(inner_num2)) / denominator
        # = （num1 - num2) / denominator
        # = numerator / denominator
        for x in exp.args:
            if x.is_Add:  # -f(x_0 - Delta(x)) + f(x_0 + Delta(x))
                numerator = x
                for n in numerator.args:
                    if n.is_Mul:  # -f(x_0 - Delta(x))
                        num2, inner_num2 = n, next(a.args[0] for a in n.args if a.is_Function)
                    else:  # f(x_0 + Delta(x))
                        num1, inner_num1 = n, n.args[0]
            else:  # 1/Delta(x)
                denominator = next(d for d in x.args if not d.is_integer)

        # 系数 = (num1 - inner_num2)/den
        xishu = (sympify(inner_num1) - sympify(inner_num2)) / sympify(denominator)
        # 极限 = f'(limit(inner_num1))
        jixian = sympify(inner_num1).subs(variable, const)
        # 结果 = 系数 * 极限
        result = "{}f'({})".format('' if xishu == 1 else new_latex(xishu), new_latex(jixian))

        intermediate = "\\lim_{{{var} \\to {value}^{{{direction}}}}} {exp}" \
            .format(var=new_latex(variable),
                    value=const,
                    exp="\\frac {{{}}} {{({}) - ({})}}".format(new_latex(numerator), new_latex(inner_num1), new_latex(inner_num2)),
                    direction=direction if direction else ' ')

        self.steps.append(["由题意 {} = {} = {}"
                          .format(self.delta_process(limit_obj.printing()),
                                  self.delta_process(intermediate), result), ])
        self.output.append(BasePoly("{}*f_d({})".format(xishu, jixian)))
        self.label.add("导数的定义式变换计算")

        return self


if __name__ == "__main__":
    pass
